#include<iostream>
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<string.h>
#include <netinet/in.h>//bind
#include <arpa/inet.h>//bind
using namespace std;

class UdpClient
{
public:
    UdpClient(string ip, uint16_t port)
    :_sockfd(-1)
    ,_ip(ip)
    ,_port(port)
    {}
    bool InitClient()
    {
        _sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if(_sockfd < 0){
            cerr<< "socket error" << endl;
            return false;//创建失败
        }
    }
    void Start()
    {
        //给谁发数据
        struct sockaddr_in server;
        server.sin_family = AF_INET;
        server.sin_port = htons(_port);
        server.sin_addr.s_addr = inet_addr(_ip.c_str());
        socklen_t len = sizeof(server);
        while(1)
        {
            std::cout << "MyShell $ ";
            char message[1024];
            fgets(message, sizeof(message), stdin);
            
            sendto(_sockfd, message, strlen(message), 0, (struct sockaddr*)&server, len);

            //此处tmp就是一个“占位符”
            struct sockaddr_in tmp;
            socklen_t tmp_len = sizeof(tmp);
            char buffer[1024];
            ssize_t s = recvfrom(_sockfd, buffer, sizeof(buffer)-1, 0, (struct sockaddr*)&tmp, &tmp_len);
            buffer[s] = '\0';
            //std::cout << "server echo# " << buffer << std::endl;

            cout << "server " << inet_ntoa(tmp.sin_addr) << ":" << ntohs(tmp.sin_port) << "#" << endl << buffer << endl;

        }
    }
private:
    int _sockfd;
    string _ip;
    uint16_t _port;
};
int main(int argc, char* argv[])
{
    if(argc != 3)
    {
        cout<<"Usage: \n\t"<< argv[0] <<" goal_IP" << " goal_port" << endl;
        return 1;
    }
    string ip = argv[1];
    uint16_t port = atoi(argv[2]);
    UdpClient* clt = new UdpClient(ip, port);
    clt->InitClient();
    clt->Start();

    return 0;
}